<script setup lang="ts">
/**
 * @desc DingPanel
 * @author DragonTeam <https://www.bpmport.com>
 * @since 2024/10/28 10:23
 */

import type { Component, PropType } from 'vue'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import NodeBasic from './children/NodeBasic.vue'
import UserTask from './children/UserTask.vue'
import UserTaskMultiInstance from './children/UserTaskMultiInstance.vue'
import NodeExpression from './children/NodeExpression.vue'
import type { BaseNode, ExpressionNode } from '@/types'
import { isUndefined } from '@/utils/typed'
import { checkExclusiveGateway } from '@/configuration/check-node-types'
import UserTaskOperation from '@/components/ding-panel/children/UserTaskOperation.vue'
import { isExpressionNode, isServiceNode, isTaskNode } from '@/utils/element-utils'
import ServiceCopyTo from '@/components/ding-panel/children/ServiceCopyTo.vue'
import ServiceMailTo from '@/components/ding-panel/children/ServiceMailTo.vue'

defineOptions({ name: 'DingPanel' })

const $props = defineProps({
  node: {
    type: Object as PropType<BaseNode>,
    default: () => ({ businessData: {} }),
  },
})
const doEmit = defineEmits(['update:node'])

const { t } = useI18n()
const headerTitle = computed(() => {
  if ($props.node.businessData?.$type) {
    return t($props.node.businessData?.$type)
  }
  return $props.node.type ? t($props.node.type) : 'Process'
})

const panelState = ref(false)
function togglePanel(state?: boolean) {
  if (!$props.node.id) {
    return (panelState.value = false)
  }
  if (isUndefined(state)) {
    return (panelState.value = !panelState.value)
  }
  panelState.value = state
}

const presetPanel: string[] = [
  'NodeBasic',
  'UserTask',
  'UserTaskMultiInstance',
  'UserTaskOperation',
  'NodeExpression',
  'ServiceCopyTo',
  'ServiceMailTo',
]
const defaultOpenPanel = ref<string[]>([...presetPanel])

const renderComponents = computed<Component[]>(() => {
  const components: Component[] = [NodeBasic]

  const businessData = $props.node.businessData
  const bpmnType = businessData.$type

  if (isTaskNode($props.node) && bpmnType === 'userTask') {
    components.push(UserTask)
    components.push(UserTaskMultiInstance)
    components.push(UserTaskOperation)
  }
  if (isServiceNode($props.node) && bpmnType === 'serviceTask') {
    if (businessData.type === 'copy') {
      components.push(ServiceCopyTo)
    }
    if (businessData.type === 'mail') {
      components.push(ServiceMailTo)
    }
  }
  if (
    isExpressionNode($props.node)
    && checkExclusiveGateway($props.node as ExpressionNode)
  ) {
    components.push(NodeExpression)
  }

  return components
})

defineExpose({
  togglePanel,
})
</script>

<template>
  <div class="ding-panel" :class="{ opened: panelState }">
    <div class="toggle-btn" @click="togglePanel()">
      <IconDoubleLeft :size="12" />
    </div>

    <div class="ding-panel_header">
      {{ headerTitle }}
    </div>
    <div v-if="node.id" class="ding-panel_body">
      <a-collapse
        v-model:active-key="defaultOpenPanel"
        :bordered="false"
        expand-icon-position="right"
        size="small"
        style="border-radius: 0"
      >
        <component
          :is="c"
          v-for="c in renderComponents"
          :key="c.name"
          :node="node"
          @update:node="doEmit('update:node', $event)"
        />
      </a-collapse>
    </div>
  </div>
</template>
